package org.summerframework.component.security.oauth.conf;

import com.alipay.api.AlipayClient;
import org.summerframework.component.security.oauth.OAuthInterceptor;
import org.summerframework.component.security.oauth.OAuthUserInfo;
import org.summerframework.component.security.oauth.OAuthUserInfoInterceptor;
import org.summerframework.component.security.oauth.alipay.AlipayAppIdAndAppSecret;
import org.summerframework.component.security.oauth.alipay.AlipayOAuthSupper;
import org.summerframework.component.security.oauth.alipay.AlipayThirdPartyOAuthSupper;
import org.summerframework.component.security.oauth.qq.QQAppIdAndAppSecret;
import org.summerframework.component.security.oauth.qq.QQMobileOAuthSupper;
import org.summerframework.component.security.oauth.qq.QQOAuthSupper;
import org.summerframework.component.security.oauth.wechat.*;
import org.summerframework.component.security.oauth.weibo.WeiboAppIdAndAppSecret;
import org.summerframework.component.security.oauth.weibo.WeiboOAuthSupper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.summerframework.component.security.oauth.wechat.*;

import java.util.List;

/**
 * @author 石超
 * @version v1.0.0
 */
@Slf4j
@Configuration
public class OAuthAutoConfiguration {

    @Bean
    public OAuthUserInfoInterceptor oAuthUserInfoInterceptor(@Autowired(required = false) List<OAuthInterceptor> oAuthInterceptors) {
        if (oAuthInterceptors == null) {
            log.warn("register oAuthUserInfoInterceptor, spring context not has OAuthInterceptor bean;");
        }

        return new OAuthUserInfo(oAuthInterceptors);
    }

    @Configuration
    @ConditionalOnProperty(prefix = "oauth.alipay", name = "app-id")
    @ConditionalOnClass(AlipayClient.class)
    public static class AlipayConfiguration {
        @Bean
        @ConfigurationProperties("oauth.alipay")
        public AlipayAppIdAndAppSecret alipayAppIdAndAppSecret() {
            return new AlipayAppIdAndAppSecret();
        }

        @Bean
        public AlipayOAuthSupper alipayOAuthSupper() {
            return new AlipayOAuthSupper(alipayAppIdAndAppSecret());
        }
    }

    @Configuration
    @ConditionalOnProperty(prefix = "oauth.alipay-third", name = "app-id")
    @ConditionalOnClass(AlipayClient.class)
    public static class AlipayThirdPartyConfiguration {

        @Bean
        @ConfigurationProperties("oauth.alipay-third")
        public AlipayAppIdAndAppSecret alipayThirdPartyAppIdAndAppSecret() {
            return new AlipayAppIdAndAppSecret();
        }

        @Bean
        public AlipayThirdPartyOAuthSupper alipayThirdPartyOAuthSupper() {
            return new AlipayThirdPartyOAuthSupper(alipayThirdPartyAppIdAndAppSecret());
        }
    }

    @Configuration
    @ConditionalOnProperty(prefix = "oauth.qq", name = "app-id")
    public static class QQConfiguration {

        @Bean
        @ConfigurationProperties("oauth.qq")
        public QQAppIdAndAppSecret qqAppIdAndAppSecret() {
            return new QQAppIdAndAppSecret();
        }

        @Bean
        public QQOAuthSupper qqoAuthSupper() {
            return new QQOAuthSupper(qqAppIdAndAppSecret());
        }
    }

    @Configuration
    @ConditionalOnProperty(prefix = "oauth.qq-mobile", name = "app-id")
    public static class QQMobileConfiguration {

        @Bean
        @ConfigurationProperties("oauth.qq-mobile")
        public QQAppIdAndAppSecret qqAppIdAndAppSecret() {
            return new QQAppIdAndAppSecret();
        }

        @Bean
        public QQMobileOAuthSupper qqMobileOAuthSupper() {
            return new QQMobileOAuthSupper(qqAppIdAndAppSecret());
        }
    }

    @Configuration
    @ConditionalOnProperty(prefix = "oauth.wechat", name = "app-id")
    public static class WechatConfiguration {

        @Autowired
        private ApplicationContext applicationContext;

        @Bean
        @ConfigurationProperties("oauth.wechat")
        public WechatAppIdAndAppSecret wechatAppIdAndAppSecret() {
            return new WechatAppIdAndAppSecret();
        }

        @Bean
        public WechatOAuthSupper wechatOAuthSupper() {
            return new WechatOAuthSupper(wechatAppIdAndAppSecret());
        }
    }

    @Configuration
    @ConditionalOnProperty(prefix = "oauth.wechat-mp", name = "app-id")
    public static class WechatMpConfiguration {

        @Bean
        @ConfigurationProperties("oauth.wechat-mp")
        public WechatMpAppIdAndAppSecret wechatMpAppIdAndAppSecret() {
            return new WechatMpAppIdAndAppSecret();
        }

        @Bean
        public WechatMpOAuthSupper wechatMpOAuthSupper() {
            return new WechatMpOAuthSupper(wechatMpAppIdAndAppSecret());
        }
    }

    @Configuration
    @ConditionalOnProperty(prefix = "oauth.wechat-mini", name = "app-id")
    public static class WechatMiniConfiguration {

        @Bean
        @ConfigurationProperties("oauth.wechat-mini")
        public WechatMiniAppsAppIdAndAppSecret wechatMiniAppsAppIdAndAppSecret() {
            return new WechatMiniAppsAppIdAndAppSecret();
        }

        @Bean
        public WechatMiniAppsOAuthSupper wechatMiniAppsOAuthSupper() {
            return new WechatMiniAppsOAuthSupper(wechatMiniAppsAppIdAndAppSecret());
        }
    }

    @Configuration
    @ConditionalOnProperty(prefix = "oauth.weibo", name = "app-id")
    public static class WeiboConfiguration {

        @Bean
        @ConfigurationProperties("oauth.weibo")
        public WeiboAppIdAndAppSecret weiboAppIdAndAppSecret() {
            return new WeiboAppIdAndAppSecret();
        }

        @Bean
        public WeiboOAuthSupper wechatOAuthSupper() {
            return new WeiboOAuthSupper(weiboAppIdAndAppSecret());
        }
    }
}
